<?php

namespace app\http\middleware;

use Closure;
use johnxu\tool\exception\InvalidSignatureException;
use johnxu\tool\exception\InvalidVerifyException;
use johnxu\tool\Jwt;
use think\db\exception\DataNotFoundException;
use think\db\exception\ModelNotFoundException;
use think\exception\DbException;
use think\Request;

class Auth
{
    private $allowAccessRule = [
        'admin/login',
        'admin/test',
    ];

    public function handle(Request $request, Closure $next)
    {
        // 去除不需要权限验证的
        if (!in_array($request->routeInfo()['rule'], $this->allowAccessRule)) {
            $payload = $this->jwtAuth($request, $next);
            // 判断用户是否有访问该接口的权限
            $this->verifyApiAuth($payload['payload'], $request);
        }

        return $next($request);
    }

    /**
     * 权限校验
     * @param Request $request
     * @param Closure $next
     * @return mixed
     */
    private function jwtAuth(Request $request, Closure $next)
    {
        $authorization = $request->header('Authorization', '');
        if (!$authorization) {
            echo json_encode(['err_code' => -1, 'message' => '登录凭证[Authorization]不存在'],
                JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
            exit();
        }
        // 验证
        $jwt = new Jwt();
        $jwt->setKey(config('johnxu.jwt_key'));
        try {
            return $jwt->verify($authorization);
        } catch (InvalidSignatureException $e) {
            echo json_encode(['err_code' => -1, 'message' => $e->getMessage()], JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);
            exit();
        } catch (InvalidVerifyException $e) {
            echo json_encode(['err_code' => -1, 'message' => $e->getMessage()], JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);
            exit();
        }
    }

    /**
     * 验证接口是否有访问权限
     * @param         $payload
     * @param Request $request
     * @throws DataNotFoundException
     * @throws ModelNotFoundException
     * @throws DbException
     */
    private function verifyApiAuth($payload, Request $request)
    {
        // 查询用户id
        $userId = model('admin')->where('username', $payload['username'])->value('id');
        // 查询用户所属角色Id
        $roleId = model('AdminRole')->where('user_id', $userId)->value('role_id');
        // 查询该角色拥有的规则Ids
        $ruleIds = model('role')->where('id', 'in', $roleId)->value('rules');
        // 查询规则列表
        $rules = model('rule')->where('id', 'in', $ruleIds)->where('status', 1)->select();
        // admin/Menu/index
        $moduleControllerAction = $request->module() . '/' . $request->controller() . '/' . $request->action();
        $toBeSeletect           = [];
        foreach ($rules as $item) {
            $tmp = strtolower($item['module']) . '/' . ucfirst($item['controller']) . '/' . strtolower($item['action']);
            array_push($toBeSeletect, $tmp);
        }
        if (!in_array($moduleControllerAction, $toBeSeletect)) {
            echo json_encode(['err_code' => -1, 'message' => '没有访问权限'], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
            exit();
        }
    }
}
